package com.qiniu.githubdata.job;

import com.qiniu.githubdata.entity.Developer;
import com.qiniu.githubdata.entity.DeveloperFollower;
import com.qiniu.githubdata.mapper.DeveloperMapper;
import com.qiniu.githubdata.utils.ProxyUtil;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHUser;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

@Component
public class GitHubPageScraper {
    @Resource
    private DeveloperMapper developerMapper;
    GitHub github = new GitHubBuilder().
            withOAuthToken("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").build();

    public GitHubPageScraper() throws IOException {
    }

    //间接 followers
    public List<Developer> getIndirectFollowers(GHUser user) throws IOException {
        List<Developer> developers = new ArrayList<>();
        int totalPage = user.getFollowersCount() / 50 + 1;
        List<Developer> directFollowers = getAndStoreAllFollowers(user);
        System.out.println("directFollowers:"+directFollowers.size());
        for (Developer directFollower : directFollowers) {
            List<Developer> followers = getAndStoreAllFollowers(getUser(directFollower.getLogin()));
            developers.addAll(followers);
        }
        return developers;
    }
    public GHUser getUser(String login) throws IOException {
        return github.getUser(login);
    }
    public List<Developer> getAndStoreAllFollowers(GHUser user) throws IOException {
        List<Developer> developers = new ArrayList<>();
        int totalPage = user.getFollowersCount() / 50 + 1;
        for (int i = 1; i <= totalPage; i++) {
            List<Developer> developersByPage = getAndSaveFollowersByPage(user, i);
            developers.addAll(developersByPage);
        }
        return developers;
    }
    public  List<Developer> getAndSaveFollowersByPage(GHUser user, int page) throws IOException {
        String userName= user.getLogin();
        String url = "https://github.com/orgs/"+userName+"/followers/?page="+page;
        if(!Objects.equals(user.getType(), "Organization")){
            url="https://github.com/"+userName+"?tab=followers";
        }
        Document doc = ProxyUtil.fetchGithubContent(url);
        if(doc==null){
            return Collections.emptyList();
        }
        Element userFrame = doc.selectFirst("#user-profile-frame");
        Elements elements = null;
        if (userFrame != null) {
            elements = userFrame.select(".d-table");
        }
        if(Objects.equals(user.getType(), "Organization")){
            elements=doc.select(".d-table");
        }
        List<Developer> developers = new ArrayList<>();

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        if(elements==null){
            return Collections.emptyList();
        }
        for (Element element : elements) {
            //<span class="Link--secondary pl-1">H-0110</span>
            //loginname
            String loginName = element.selectFirst(".Link--secondary").text();
            String firstElement = element.selectFirst(".Link--primary").text();
            Element mr3=element.selectFirst(".mr-3");
            String nation= null;
            String organization=null;
            if(mr3!=null){
                String mr3Text=mr3.text();
                organization=mr3Text;
                System.out.println(mr3Text);
            }
            Element mb0=element.selectFirst(".mb-0");
            if(mb0!=null) {
                String mb0Text = mb0.text();
                nation=mb0Text;
                System.out.println(mb0Text);
            }

//                    System.out.println(firstElement);
//                    System.out.println(loginName);
            //<img class="avatar avatar-user"
            // src="https://avatars.githubusercontent.com/u/43487278?s=100&amp;v=4"
            // width="50" height="50" alt="@wallleap">
            Element img=element.selectFirst(".avatar");
            String src = null;
            long id = -1;
            if(img!=null) {
                src = img.attr("src");
                //get id from img url
                String[] split = src.split("\\?");
                String[] split1 = split[0].split("/");
                id = Integer.parseInt(split1[split1.length - 1]);
            }
            Developer developer = new Developer();
            developer.setLogin(loginName);
            developer.setUserName(firstElement);
            developer.setId((long) id);
            developer.setAvatarUrl(src);
            developer.setNation(nation);
            if(nation!=null){
                developer.setNationConfidence(1);
            }
//                        developer.setOrganization(organization);
            String githubUrl="https://github.com/"+loginName;
            developer.setGithubUrl(githubUrl);
            developers.add(developer);
            System.out.println(nation);
            //get id from img url
            developerMapper.insertOrUpdateDeveloper(developer);
            developerMapper.insertFollowerIfNotExist(new DeveloperFollower(user.getId(),developer.getId()));
        }
        stopWatch.stop();
        System.out.println("page "+page+" cost time:"+stopWatch.getTotalTimeSeconds()+" save number:"+developers.size());
        return developers;
//        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
//            HttpGet request = new HttpGet(url);
//            try (CloseableHttpResponse response = httpClient.execute(request)) {
//                String html = EntityUtils.toString(response.getEntity());
////                Document doc = Jsoup.parse(html);
//                //id="user-profile-frame"
//                Element userFrame = doc.selectFirst("#user-profile-frame");
//                Elements elements = null;
//                if (userFrame != null) {
//                    elements = userFrame.select(".d-table");
//                }
//                if(Objects.equals(user.getType(), "Organization")){
//                    elements=doc.select(".d-table");
//                }
//                List<Developer> developers = new ArrayList<>();
//
//                StopWatch stopWatch = new StopWatch();
//                stopWatch.start();
//                if(elements==null){
//                    return Collections.emptyList();
//                }
//                for (Element element : elements) {
//                    //<span class="Link--secondary pl-1">H-0110</span>
//                    //loginname
//                    String loginName = element.selectFirst(".Link--secondary").text();
//                    String firstElement = element.selectFirst(".Link--primary").text();
//                   Element mr3=element.selectFirst(".mr-3");
//                   String nation= null;
//                   String organization=null;
//                   if(mr3!=null){
//                       String mr3Text=mr3.text();
//                       organization=mr3Text;
//                   System.out.println(mr3Text);
//                   }
//                   Element mb0=element.selectFirst(".mb-0");
//                     if(mb0!=null) {
//                         String mb0Text = mb0.text();
//                            nation=mb0Text;
//                         System.out.println(mb0Text);
//                     }
//
////                    System.out.println(firstElement);
////                    System.out.println(loginName);
//                    //<img class="avatar avatar-user"
//                    // src="https://avatars.githubusercontent.com/u/43487278?s=100&amp;v=4"
//                    // width="50" height="50" alt="@wallleap">
//                    Element img=element.selectFirst(".avatar");
//                        String src = null;
//                        long id = -1;
//                        if(img!=null) {
//                            src = img.attr("src");
//                            //get id from img url
//                            String[] split = src.split("\\?");
//                            String[] split1 = split[0].split("/");
//                             id = Integer.parseInt(split1[split1.length - 1]);
//                        }
//                        Developer developer = new Developer();
//                        developer.setLogin(loginName);
//                        developer.setUserName(firstElement);
//                        developer.setId((long) id);
//                        developer.setAvatarUrl(src);
//                        developer.setNation(nation);
//                        if(nation!=null){
//                            developer.setNationConfidence(1);
//                        }
////                        developer.setOrganization(organization);
//                        String githubUrl="https://github.com/"+loginName;
//                        developer.setGithubUrl(githubUrl);
//                        developers.add(developer);
//                        System.out.println(nation);
//                    //get id from img url
//                    developerMapper.insertOrUpdateDeveloper(developer);
//                    developerMapper.insertFollowerIfNotExist(new DeveloperFollower(user.getId(),developer.getId()));
//                }
//                stopWatch.stop();
//                System.out.println("page "+page+" cost time:"+stopWatch.getTotalTimeSeconds()+" save number:"+developers.size());
//                return developers;
//            }
//        } catch (IOException | ParseException e) {
//            e.printStackTrace();
//        }
//        return Collections.emptyList();
    }

    public List<GHRepository> getAndSaveReposByPageWithOwnerName(GHUser user, int page) throws IOException {
        String userName= user.getLogin();
        //https://github.com/TommyZihao?page=2&tab=repositories
        String url = "https://github.com/"+userName+"?page="+page+"&tab=repositories";
        Document doc = ProxyUtil.fetchGithubContent(url);
        Elements elements = doc.select("li");
        List<GHRepository> repositories = new ArrayList<>();
        if(elements==null){
            return Collections.emptyList();
        }
        for(Element element:elements){
//                    <a class="Link--muted mr-3" href="/TommyZihao/PointWise_Body/stargazers">
//                              <svg aria-label="star" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star">
//                        <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
//                    </svg>
//                              46
//                            </a><a class="Link--muted mr-3" href="/TommyZihao/PointWise_Body/stargazers">
//                              <svg aria-label="star" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star">
//                        <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
//                    </svg>
//                              46
//                            </a>
            Elements as = element.select("a");
            int starCount = -1;
            String repoName = null;
            String language = null;
            int forkCount = -1;
            for(Element a:as){
                //d-inline-block mb-1
                Element dInlineBlock = a.selectFirst(".d-inline-block");
                if(dInlineBlock!=null){
                    repoName = dInlineBlock.text();
                }
                if(a.attr("href").contains("/stargazers")){
                    String text = a.text();
                    starCount = Integer.parseInt(text);
                }
                if(a.attr("href").contains("/forks")){
                    String text = a.text();
                    forkCount = Integer.parseInt(text);
                }
            }
        }
        return repositories;
//        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
//            HttpGet request = new HttpGet(url);
//            try (CloseableHttpResponse response = httpClient.execute(request)) {
//                String html = EntityUtils.toString(response.getEntity());
////                Document doc = Jsoup.parse(html);
//                Elements elements = doc.select("li");
//                List<GHRepository> repositories = new ArrayList<>();
//                for(Element element:elements){
////                    <a class="Link--muted mr-3" href="/TommyZihao/PointWise_Body/stargazers">
////                              <svg aria-label="star" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star">
////                        <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
////                    </svg>
////                              46
////                            </a><a class="Link--muted mr-3" href="/TommyZihao/PointWise_Body/stargazers">
////                              <svg aria-label="star" role="img" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star">
////                        <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
////                    </svg>
////                              46
////                            </a>
//                    Elements as = element.select("a");
//                    int starCount = -1;
//                    String repoName = null;
//                    String language = null;
//                    int forkCount = -1;
//                    for(Element a:as){
//                        //d-inline-block mb-1
//                        Element dInlineBlock = a.selectFirst(".d-inline-block");
//                        if(dInlineBlock!=null){
//                            repoName = dInlineBlock.text();
//                        }
//                        if(a.attr("href").contains("/stargazers")){
//                            String text = a.text();
//                            starCount = Integer.parseInt(text);
//                        }
//                        if(a.attr("href").contains("/forks")){
//                            String text = a.text();
//                            forkCount = Integer.parseInt(text);
//                        }
//                    }
//                }
//                return repositories;
//            }
//        } catch (IOException | ParseException e) {
//            e.printStackTrace();
//        }
//        return Collections.emptyList();
    }
    public static void main(String[] args) {
        for (int i = 1; i < 10; i++) {
//            followerScrape("alibaba",i);
        }
    }
}